#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;

const int MAX_STRING_LENGTH = 1000;

void add(string fileName, string textLine)
{
	fstream fileStream;
	fileStream.open(fileName, fstream::in | fstream::app); // allow write operations to end of file

	if (!fileStream.is_open()){			// check if file is open
		throw ("Unable to open file!");
	}

	fileStream << textLine << endl;		// ouput line to file
	fileStream.close();					// flush buffer
}

void display(string fileName)
{
	fstream fileStream;
	fileStream.open(fileName, fstream::in); // allow only reading

	if (!fileStream.is_open()){				// test if file is open
		throw ("Unable to open file!");
	}

	// read every line until all characters are consumed
	string line;
	for (int numLines = 1; !getline(fileStream, line).fail(); numLines++)
	{
		cout << numLines << ". " << line << endl;
	}
	
	fileStream.close();					// exit file
}

void deleteLine(string fileName, int lineNo)
{
	fstream fileStream;					     // original file
	fileStream.open(fileName, fstream::in); // allow only reading
	
	if (!fileStream.is_open()){				// test if file is open
		throw ("Unable to open file!");
	}
	
	vector<string> textRecord;
	// read every line until all characters are consumed
	string line;
	for (int numLines = 1; !getline(fileStream, line).fail(); numLines++){
		if (numLines == lineNo)	// ignore deleted line
			continue;
		textRecord.push_back(line);
	}

	fileStream.close();					// exit files
	fileStream.open(fileName, fstream::out | fstream::trunc); // delete all existing contents
	if (!fileStream.is_open()){
		throw ("Unable to open file!");
	}

	for (vector<string>::iterator i = textRecord.begin();
		 i != textRecord.end();
		 i++){
		fileStream << *i << endl;
	}
	fileStream.close();

}

int main(int argc, char* argv[])
{
	// test for correct number of variables
	if (argc < 2){
		cout << "Too few arguments. Please enter the input/ouput file name as an argument" << endl;
		return 1;
	}else if (argc > 2){
		cout << "Too many arguments. Please only enter the input/ouput file name as an argument" << endl;
		return 1;
	}

	string fileName = argv[1];

	while (true){ 
		string input; 
		getline(cin, input);			// get line of input, including command
		stringstream strStream(input);	// extract formatted output

		string cmd;
		if ((strStream >> cmd).fail()){ // ensure a command is entered
			cout << "Please enter a command!" << endl;
			continue;
		}

		if (cmd == "add"){
			string stringToAdd;
			strStream >> ws;	// ignore leading whitespace
			if (strStream.eof())						// test for possibility of pure whitespace string
			{
				cout << "Please enter a valid string to add!" << endl;
				continue;
			}
			getline(strStream, stringToAdd);			// read the rest of the input line
			add(fileName,  stringToAdd);				// 
			cout << "Added to " << fileName << ": " << "\"" << stringToAdd << "\"" << endl;
		}else if(cmd == "display"){
			display(fileName);
		}else if (cmd == "delete"){						
			int lineNo;
			strStream >> lineNo;
			if (strStream.fail()){
				cout << "Please enter a line number to delete" << endl;
				continue;
			}
			deleteLine(fileName, lineNo);

		}else if (cmd == "exit"){
			break;										// end of this line of command
		}else {
			cout << "Invalid command!" << endl;			// 
		}
		
	}

	return 0;
}